package commonDataStructures;

import java.util.ArrayList;

/**
 * this class implements a gridList, its an advance 2D array who offers
 * another none trivial operations on it
 */
//###############
//FILE : GridList.java
//WRITER : Yosef Krumbein, yokrum, 015708837
//WRITER : Avishai Lazar, avishl02, 066641200
//EXERCISE : oop ex4 2008
//DESCRIPTION: this class 
//
//###############
public class GridList<E>{

	/**
	 * the representation of the grid itself 
	 */
	protected ArrayList<ArrayList<E>> _gridList = new ArrayList<ArrayList<E>>();

	/**
	 * this method creates a blank line for the GridList
	 * @param size the size of the line
	 * @return a new blank line of the GridList
	 */
	protected ArrayList<E> createLine(int size){
		ArrayList<E> line = new ArrayList<E>(size);
		for (int i=0;i<size;i++){
			line.add(i,null);
		}
		return line;
	}

	/**
	 * empty ctor 
	 */
	protected GridList(){

	}

	/**
	 * this method sets a line inside the grid
	 * @param line the line number to set
	 * @param s the data to set
	 */
	public void setLine(int line,ArrayList<E> s){
		_gridList.set(line,s);
	}
	
	/**
	 * the method get a specific line from the GridList
	 * @param y the line to get
	 * @return the relevant line from the GridList
	 */
	public ArrayList<E> getLine(int y){
		return _gridList.get(y);
	}
	
	/**
	 * ctor who construct a GridList with a given height and width
	 * @param width the GridList's width
	 * @param height the GridList's height
	 */
	public GridList(int width,int height){
		if (width<0||height<0){
			throw new IllegalArgumentException();
		}
		_gridList = new ArrayList<ArrayList<E>>(height);
		for (int i=0;i<height;i++){
			_gridList.add(i, createLine(width));
		}

	}
	
	public GridList(GridList<E> other){
		_gridList = new ArrayList<ArrayList<E>>(other.size());
		
		for(int i=0;i<other.size();i++){
			_gridList.add(new ArrayList<E>());
		}
		
		for(int i=0;i<other.size();i++){
			for (int j=0;j<other.getLine(i).size();j++){
				_gridList.get(i).add(other.getLine(i).get(j));
			}
		}
	}

	/**
	 * ctor who construct a GridList with a given height
	 * @param height the height of the GridList
	 */
	public GridList(int height){
		this(0,height);
	}

	/**
	 * the method sets the length of specific line
	 * @param line the line to set
	 * @param length the length of the line to set
	 */
	public void setLineLength(int line,int length){
		_gridList.set(line, createLine(length));
	}

	/**
	 * the method gets an Element from the  GridList 
	 * @param y the line number
	 * @param x the column number
	 * @return the Element at the given location
	 */
	public E get(int y,int x){
		return _gridList.get(y).get(x);
	}

	/**
	 * the method adds an element to a given row
	 * @param y the row
	 * @param e the element to add
	 */
	public void add(int y,E e){
		_gridList.get(y).add(e);
	}
	
	/**
	 * the method sets an element inside the GridList
	 * @param y the row number
	 * @param x the column number
	 * @param e the element to set
	 */
	public void set(int y,int x,E e){
		_gridList.get(y).set(x,e);
	}

	/**
	 * the method gets the size (height) of the GridList
	 * @return the size of the GridList
	 */
	public int size(){
		return _gridList.size();
	}
	
	/**
	 * the method gets the size of a specific row at the GridList
	 * @param y the row number
	 * @return the size of the relevant row
	 */
	public int size(int y){
		return _gridList.get(y).size();
	}
	
	public int getWidth(){
		return size(0);
	}
	
	public int getHeight(){
		return size();
	}
	
	public void print(){
		for(int i=size()-1;i>=0;i--){
			for(int j=0;j<size(i);j++){
				System.out.print(get(i, j));
				if(j+1<size(i)) System.out.print(",");
			}
			System.out.println();
		}
	}
	public static void main(String[] args){
		GridList<String> g = new GridList<String>(2,2);
		g.set(0, 0, "A");
		g.set(1, 0, "B");
		g.set(0, 1, "C");
		g.set(1, 1, "B");
		
		GridList<String> g1 = new GridList<String>(g);
		for(int i=g1.size()-1;i>=0;i--){
			for(int j=0;j<g1.size(i);j++){
				System.out.print(g1.get(i, j));
			}
			System.out.println();
		}
		
		g.print();
	}
}
